package com.dong.curator;



import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;
import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.api.ExistsBuilder;
import org.apache.curator.framework.recipes.cache.*;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.curator.retry.RetryNTimes;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.ZooDefs;
import org.apache.zookeeper.data.Stat;

import java.util.List;

/**
 * @author: dzj
 * @date 2018/10/10-15:12
 */
public class CuratorOperator {
    public CuratorFramework client = null;
    public static final String zkServerPath = "10.0.109.142:2181";

    public CuratorOperator() {
       //new  ExponentialBackoffRetry(1000,5);
        try {

            RetryPolicy retryPolicy = new RetryNTimes(3,2000);
            client = CuratorFrameworkFactory
                    .builder()
                    .connectString(zkServerPath)
                    .sessionTimeoutMs(18000)
                    .retryPolicy(retryPolicy)
                    .namespace("workspace")
                    .build();
            client.start();
        }catch (Exception e) {
            e.printStackTrace();
        }
    }
    public void closeZkClient() {
        if(client!=null) {
            client.close();
        }
    }

    public static void main(String[] args) throws Exception {
        CuratorOperator cto = new CuratorOperator();
        boolean started = cto.client.isStarted();
        System.out.println("当前客户端状态: "+(started?"连接中":"已连接"));


        System.out.println("创建节点...............");
        String nodePath = "/super/imooc";
        byte[] data = "superme".getBytes();
     /*   cto.client.create()
                .creatingParentsIfNeeded()
                .withMode(CreateMode.PERSISTENT)
                .withACL(ZooDefs.Ids.OPEN_ACL_UNSAFE)
                .forPath(nodePath,data);*/
     //   System.out.println("修改节点...............");
     //   data = "update".getBytes();
      //  cto.client.setData().withVersion(0).forPath(nodePath,data);

       // System.out.println("删除节点");
      // cto.client.delete().guaranteed().deletingChildrenIfNeeded().withVersion(1).forPath(nodePath);

/**查询节点*/
        Stat stat = new Stat();
        byte[] bytes = cto.client.getData().storingStatIn(stat).forPath(nodePath);
        System.out.println("节点 "+nodePath+ "的数据为: "+new String (data));
        System.out.println("改节点的版本号为: "+stat.getVersion());

        Stat stat1 = cto.client.checkExists().forPath(nodePath);
        System.out.println(stat1);


      //  byte[] bytes1 = cto.client.getData().usingWatcher(new MyCuratorWatcher()).forPath(nodePath);
      //  System.out.println(new String(bytes1));
        final NodeCache nodeCache = new NodeCache(cto.client,nodePath);
        nodeCache.start(true);
        if(nodeCache.getCurrentData()!=null) {
            System.out.println("节点初始化数据为: "+new String(nodeCache.getCurrentData().getData()));
        }else {
            System.out.println("节点初始化数据为空...");
        }
        nodeCache.getListenable().addListener(new NodeCacheListener() {
            @Override
            public void nodeChanged() throws Exception {
                String data = new String(nodeCache.getCurrentData().getData());
                System.out.println("节点路径: "+nodeCache.getCurrentData().getPath()+" 数据: "+data);
            }
        });
        String childNodePathCache = nodePath;
        final PathChildrenCache childrenCache = new PathChildrenCache(cto.client,childNodePathCache,true);

        childrenCache.start(PathChildrenCache.StartMode.POST_INITIALIZED_EVENT);

        List<ChildData> childNodes = childrenCache.getCurrentData();
        System.out.println("获取当前节点的子节点数据列表 数量: "+childNodes.size());
        for (ChildData currentDatum : childNodes) {
            System.out.println(new String(currentDatum.getData()));
        }
        childrenCache.getListenable().addListener((client,event) -> {
            PathChildrenCacheEvent.Type type = event.getType();
            if(type.equals(PathChildrenCacheEvent.Type.INITIALIZED)) {
                System.out.println("子节点初始化ok");
            }else if(type.equals(PathChildrenCacheEvent.Type.CHILD_ADDED)) {
                System.out.println("添加子节点 : "+event.getData().getPath()+", 数据: "+new String(event.getData().getData()));
            }else if(type.equals(PathChildrenCacheEvent.Type.CHILD_REMOVED)) {
                System.out.println("删除子节点: "+event.getData().getPath());
            }else if(type.equals(PathChildrenCacheEvent.Type.CHILD_UPDATED)) {
                System.out.println("修改子节点数据 "+event.getData().getPath()+ ", 更新后数据为: "+new String(event.getData().getData()));

            }
        });


        Thread.sleep(3300000);
        cto.closeZkClient();
        boolean started1 = cto.client.isStarted();
        System.out.println("当前客户端状态: "+(started1?"连接中":"已连接"));
    }
}
